<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    // 垃圾回收机制（GC）：JS中内存的分配和回收都是自动完成的，内存在不使用时会被垃圾回收器自动回收

    // 内存的生命周期：
    // 1.内存分配：当我们声明变量、函数、对象的时候，系统会自动的为他们分配内存
    // 2.内存使用：即读写内存，也就是使用变量、函数等
    // 3.内存回收：使用完毕，由垃圾回收器自动回收不再使用的内存

    // 为变量分配内存
    const age = 18
    // 为对象分配内存
    const obj = {
      age: 19
    }
    // 为函数分配内存
    function fn() {
      const age = 18
      console.log(age)
    }

    // 全局变量一般不会回收（关闭页面回收）
    // 一般情况下局部变量的值，不用了，会被自动回收掉

    // 内存泄漏：程序中分配的内存由于某种原因程序未释放或无法释放叫做内存泄漏



    // JS垃圾回收机制-算法说明
    // 堆栈空间分配区别：
    // 1.栈（操作系统）：由操作系统自动分配函数的参数值、局部变量等。基本数据类型放到栈里面
    // 2.堆（操作系统）：一般由程序员分配释放，若程序员不释放，由垃圾回收机制回收。复杂数据类型放到堆里面

    // 俩种常见的浏览器垃圾回收算法：引用计数法 和 标记清除法
    // 引用计数存在一个致命问题：嵌套引用（循环引用）
    // 如果两个对象相互引用，尽管他们已经不再使用，垃圾回收机器不会进行回收，导致内存泄漏
    function fn() {
      let a = {}
      let b = {}
      a.i = b
      b.i = a
      return '引用计数无法回收'
    }  //他们的引用次数永远不会是0，会导致大量的内存泄漏

    // 标记清除法 核心思路：从根部扫描对象，能查到的就是使用的，查不到的就要回收
  </script>
</body>

</html>